package com.divemotor.ventarepuestosinternet.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.divemotor.ventarepuestosinternet.beans.adapter.DataAdapter;
import com.divemotor.ventarepuestosinternet.dao.SubGrupoDAO;
import com.divemotor.ventarepuestosinternet.model.Grupo;
import com.divemotor.ventarepuestosinternet.model.Imagen;
import com.divemotor.ventarepuestosinternet.model.SubGrupo;
import com.divemotor.ventarepuestosinternet.model.VehiculoExtra;
import com.divemotor.ventarepuestosinternet.util.Constantes;
import com.divemotor.ventarepuestosinternet.util.DatosDeSession;

@SuppressWarnings("unchecked")
@Repository (value = "SubGrupoDAO")
public class SubGrupoDAOImpl implements SubGrupoDAO , Serializable{

	private static final long serialVersionUID = -3930582465885842722L;
	
	@Autowired
	private SessionFactory sessionFactory;
	
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	
	@Override
	public void insertar(SubGrupo subGrupo) {
		getSessionFactory().getCurrentSession().persist(subGrupo);
	}

	@Override
	public void actualizar(SubGrupo subGrupo) {
		getSessionFactory().getCurrentSession().merge(subGrupo);
	}

	@Override
	public List<SubGrupo> listar() {
		Criteria  criteria = getSessionFactory().getCurrentSession().createCriteria(SubGrupo.class, "subGrupo")
				.createAlias("subGrupo.grupo", "grupo")
				.add(Restrictions.not(Restrictions.eq("estado", Constantes.ESTADO_ELIMINADO)))
				.addOrder(Order.asc("subGrupo.nombre"));
		return  criteria.list();
	}

	@Override
	public void eliminar(SubGrupo subGrupo) {
		getSessionFactory().getCurrentSession().merge(subGrupo);
	}

	@Override
	public List<SubGrupo> buscar(SubGrupo subGrupo) {
		Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(SubGrupo.class, "subGrupo")
				.createAlias("subGrupo.grupo", "grupo");
		
		String porc   = Constantes.PORCENTAJE;
		
		if(!subGrupo.getCodigo().equals("")){
			 criteria.add(Restrictions.like("subGrupo.codigo", porc + subGrupo.getCodigo() + porc).ignoreCase());
		  }
		
		 if(!subGrupo.getNombre().equals("")){
			 criteria.add(Restrictions.like("subGrupo.nombre", porc + subGrupo.getNombre() + porc).ignoreCase());
		 }
		 
		 if(!(subGrupo.getGrupo().getIdGrupo().equals(Constantes.NO_SELECCIONADO))){
			 criteria.add(Restrictions.eq("grupo.idGrupo", subGrupo.getGrupo().getIdGrupo()));	 
		 }
		 
		 if(!subGrupo.getEstado().equals(Constantes.STR_NO_SELECCIONADO)){
			 criteria.add(Restrictions.eq("subGrupo.estado", subGrupo.getEstado()));
		 }
		 
		 criteria.add(Restrictions.not(Restrictions.eq("subGrupo.estado", Constantes.ESTADO_ELIMINADO)));
		 
		return criteria.list();
	}
	
	@Override
	public List<DataAdapter> buscarPorGrupo(Integer idGrupo){
		Query q = sessionFactory.getCurrentSession().getNamedQuery("SubGrupo.obtenerPorGrupo");
		q.setParameter("grupo", idGrupo);
		return q.list();
	}

	@Override
	public SubGrupo obtenerPorNombre(SubGrupo subGrupo) {
		Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(SubGrupo.class, "subGrupo")
				.createAlias("subGrupo.grupo", "grupo")
				.add(Restrictions.eq("subGrupo.nombre",subGrupo.getNombre()).ignoreCase())
				.add(Restrictions.not(Restrictions.eq("subGrupo.estado",Constantes.ESTADO_ELIMINADO)));
		return (SubGrupo) criteria.uniqueResult();
	}

	@Override
	public List<SubGrupo> listarPorGrupo(SubGrupo subGrupo) {
		Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(SubGrupo.class, "subGrupo")
				.createAlias("subGrupo.grupo", "grupo")
				.add(Restrictions.eq("grupo.pais", DatosDeSession.obtenerPaisDelUsuarioAutenticado()))
				.add(Restrictions.eq("grupo.idGrupo", subGrupo.getGrupo().getIdGrupo()))
				.add(Restrictions.not(Restrictions.eq("subGrupo.estado",Constantes.ESTADO_ELIMINADO)));
		return criteria.list();
	}
	
	@Override
	public SubGrupo obtenerPorCodigoSAP(SubGrupo subGrupo) {
		Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(SubGrupo.class, "subGrupo")
				.createAlias("subGrupo.grupo", "grupo")
				.add(Restrictions.eq("subGrupo.codigo", subGrupo.getCodigo()).ignoreCase())
				.add(Restrictions.not(Restrictions.eq("subGrupo.estado",Constantes.ESTADO_ELIMINADO)));
		return (SubGrupo) criteria.uniqueResult();
	}

	@Override
	public SubGrupo obtenerPorId(SubGrupo subGrupo) {
		return (SubGrupo) sessionFactory.getCurrentSession().get(SubGrupo.class, subGrupo.getIdSubGrupo());
	}

	@Override
	public List<DataAdapter> listarSubGruposPorVehiculoYGrupo(String chasis, Integer idGrupo, String tipoComponente) {
		return sessionFactory.getCurrentSession().getNamedQuery("SubGrupos.comboSubGruposVehiculos")
												 .setParameter("chasis", chasis)
												 .setParameter("grupo", idGrupo)
												 .setParameter("tipoComponente", tipoComponente).list();
	}

	@Override
	public List<SubGrupo> listarSubGruposPorVehiculoExtraYGrupo(VehiculoExtra vehiculoExtra, Grupo grupo) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Imagen.class, "imagen")
				.createAlias("imagen.modeloFabrica", "modeloFabrica")
				.createAlias("modeloFabrica.listaModelo", "modelo")
				.createAlias("modelo.listaVehiculoExtra", "vehiculoExtra")
				.createAlias("imagen.subGrupo", "subGrupo")
				.createAlias("subGrupo.grupo", "grupo")
				.setProjection(Projections.projectionList().add(Projections.distinct(Projections.property("subGrupo.idSubGrupo"))))
				.add(Restrictions.eq("vehiculoExtra.idVehiculoExtra", vehiculoExtra.getIdVehiculoExtra()))
				.add(Restrictions.eq("subGrupo.estado", Constantes.ESTADO_ACTIVO))
				.add(Restrictions.eq("grupo.idGrupo", grupo.getIdGrupo()));
		
		return listarSubGruposPorIds(criteria.list());
	}

	@Override
	public List<SubGrupo> listarSubGruposPorIds(List<Integer> listaIdsSubGrupos) {
		if (listaIdsSubGrupos != null && listaIdsSubGrupos.size() > 0) {
			Criteria criteria = sessionFactory.getCurrentSession().createCriteria(SubGrupo.class, "subGrupo")
					.createAlias("subGrupo.grupo", "grupo")
					.add(Restrictions.in("subGrupo.idSubGrupo", listaIdsSubGrupos))
					.addOrder(Order.asc("subGrupo.nombre"));
			return criteria.list();
		} else {
			return null;
		}
	}

}
